/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.context.support;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Nullable;

/**
 * Delegate for AbstractApplicationContext's post-processor handling.
 *
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 4.0
 */
final class PostProcessorRegistrationDelegate {

	private PostProcessorRegistrationDelegate() {
	}


	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		// 第一步：首先调用 BeanDefinitionRegistryPostProcessor 的后置处理器
		// 放置 beanName，后续会根据这个集合来判断处理器是否已经被执行过了
		Set<String> processedBeans = new HashSet<>();

		// 判断beanFactory是否是 BeanDefinitionRegistry 类型，并强行把其转为 BeanDefinitionRegistry
		if (beanFactory instanceof BeanDefinitionRegistry registry) {
			// 保存 BeanFactoryPostProcessor 类型的后置处理器
			// 用来装载BeanFactoryPostProcessor，只有一个实现方法postProcessBeanFactory()
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 用来装载 BeanDefinitionRegistryPostProcessor，它继承了 BeanFactoryPostProcessor
			// 不仅有postProcessBeanFactory()还有postProcessBeanDefinitionRegistry()
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
			// 循环传递进来的 BeanFactoryPostProcessor ，正常情况下无数据，只有手动添加了后置处理器才会有数据
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// 判断后置处理器是不是 BeanDefinitionRegistryPostProcessor
				// 因为 BeanDefinitionRegistryPostProcessor 扩展了 BeanFactoryPostProcessor
				// jdk语法糖，强转类型，并赋值给变量 registryProcessor
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
					// 调用 BeanDefinitionRegistryPostProcessor 的处理器的后置方法
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					// 添加到用于保存的 BeanDefinitionRegistryPostProcessor 的集合中
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// 定义一个集合用于保存当前准备创建的 BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
			// internalConfigurationAnnotationProcessor 即 ConfigurationAnnotationProcessor
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 循环上一步获取的 BeanDefinitionRegistryPostProcessor 的类型名称
			for (String ppName : postProcessorNames) {
				// 判断是否实现了 PriorityOrdered 接口
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// 显示的调用 getBean() 的方式获取出该对象，然后加入到 currentRegistryProcessors 集合中去
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 同时也加入到 processedBeans 集合中去
					// 后续会根据这个集合来判断处理器是否已经被执行过
					processedBeans.add(ppName);
				}
			}
			// 对 currentRegistryProcessors 集合中的 BeanDefinitionRegistryPostProcessor 进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 把他加入到用于保存的 registryProcessors 中
			// 为什么要合并，因为 registryProcessors 是装载 BeanDefinitionRegistryPostProcessor 的
			// 一开始的时候，spring只会执行 BeanDefinitionRegistryPostProcessor 的独有方法
			// 而不会执行 BeanDefinitionRegistryPostProcessor 的父类的方法，即 BeanFactoryProcessor 的方法
			// 所以这里要把处理器放入一个集合中，后续统一执行父类的方法
			registryProcessors.addAll(currentRegistryProcessors);
			/*
				在这里典型的 BeanDefinitionRegistryPostProcessor 就是 ConfigureClassPostProcessor
				用于进行 bean 定义的加载，比如我们的包扫描 @Import 等
			 */
			// spring 热插拔的体现，像 BeanDefinitionRegistryPostProcessor 就相当于一个组件
			// spring 很多事情就是交给组件去管理的，如果不想用这个组件，直接去掉注册组件就行了
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			// 调用完之后，马上 clear 掉，临时变量需要清除
			// list.clear()只清除对象的引用使其变为垃圾，与 list = null 集合也会置空
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 接下来，去容器中获取 BeanDefinitionRegistryPostProcessor 的 bean 处理器名称
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			// 循环上一步获取到的 BeanDefinitionRegistryPostProcessor 的类型名称
			for (String ppName : postProcessorNames) {
				// 没有被处理过，并且实现了 Ordered 接口
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					// 显示的调用 getBean() 的方式获取出该对象然后加入到 currentRegistryProcessors 集合中去
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 同时也加入到 processedBeans 集合中去
					processedBeans.add(ppName);
				}
			}
			// 对 currentRegistryProcessors 集合中 BeanDefinitionRegistryPostProcessor 进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 把他加入到用于保存的 registryProcessors 中
			registryProcessors.addAll(currentRegistryProcessors);
			// 调用他的后置处理方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			// 调用完之后，马上clear掉
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 调用没有实现任何优先级接口的 BeanDefinitionRegistryPostProcessor
			// 定义一个重复处理的开关变量 默认值为 true
			boolean reiterate = true;
			// 第一次就可以进来
			while (reiterate) {
				// 进入循环马上把开关变量给改为false
				reiterate = false;
				// 去容器中获取 BeanDefinitionRegistryPostProcessor 的 bean 的处理器名称
				// 根据类型查 beanName ，一般情况下只会获取到一个，
				// org.springframework.context.annotation.internalConfigurationAnnotationProcessor，
				// 也就是 ConfigurationAnnotationProcessor
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				// 循环上一步获取的 BeanDefinitionRegistryPostProcessor 的类型名称
				for (String ppName : postProcessorNames) {
					// 没有被处理过的
					if (!processedBeans.contains(ppName)) {
						// 显示的调用 getBean() 的方式获取出该对象然后加入到 currentRegistryProcessors 集合中去
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						// 同时也加入到processedBeans集合中去
						processedBeans.add(ppName);
						// 再次设置为true
						reiterate = true;
					}
				}
				// 对 currentRegistryProcessors 集合中 BeanDefinitionRegistryPostProcessor 进行排序
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				// 把他加入到用于保存的 registryProcessors 中
				registryProcessors.addAll(currentRegistryProcessors);
				// 调用他的后置处理方法
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
				// 调用完之后，马上clear掉
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 调用实现了 BeanDefinitionRegistryPostProcessor 的接口 他也同时实现了 BeanFactoryPostProcessor 的方法
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			// 调用 BeanFactoryPostProcessor 成品的不是通过 getBean 的
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			// 若当前的 beanFactory 没有实现 BeanDefinitionRegistry，也就不需要去调用 postProcessBeanDefinitionRegistry 方法
			// 直接调用 BeanFactoryPostProcessor 接口的 postProcessBeanFactory 方法进行后置处理
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// 获取容器中所有的 BeanFactoryPostProcessor
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 保存 BeanFactoryPostProcessor 类型实现了 PriorityOrdered 接口的
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// 保存 BeanFactoryPostProcessor 类型实现了 Ordered 接口的
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 保存 BeanFactoryPostProcessor 没有实现任何优先级接口的
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			// processedBeans 包含的话，表示在上面处理 BeanDefinitionRegistryPostProcessor 的时候处理过了
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			// 判断是否实现了 PriorityOrdered 接口
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			// 判断是否实现了 Ordered 接口
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			// 没有实现任何的优先级接口的
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		// 首先，先调用 BeanFactoryPostProcessor 实现了 PriorityOrdered 接口的，先排序，再调用
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		// 再调用 BeanFactoryPostProcessor 实现了 Ordered 接口的
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		// 最后调用没有实现任何方法接口的
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();

		/*
			总结：
			首先，之前已经了解过 BeanDefinition 的两个扩展点 postProcessBeanFactory 和 postProcessBeanDefinitionRegistry。
			前者可以修改 BeanDefinition，重写方法，后者可以添加 BeanDefinition
			1、定义了一个 Set，processedBeans 装载 BeanName，后面会根据此 Set 来判断后置处理器是否被执行过

			2、判断当前的 beanFactory 有没有实现 BeanDefinitionRegistry，当然是肯定的，
			定义了两个 List 一个是 regularPostProcessors，用来装载 BeanFactoryPostProcessor。它只有一个实现
			方法 postProcessBeanFactory()。一个是 registryProcessors，用来装载 BeanDefinitionRegistryPostProcessor。因为
			它继承了 BeanFactoryPostProcessor 它不仅有 postProcessBeanFactory() 还有 postProcessBeanDefinitionRegistry()。

			3、循环传进来的 beanFactoryPostProcessors，一般情况下都是空的，除非自己 add 了 beanFactory 的后置处理器。
			假设有数据，先判断是否是 BeanDefinitionRegistryPostProcessor ，
			如果是调用 postProcessBeanDefinitionRegistry() 方法，并添加到集合 registryProcessors 中，
			否的话直接加入到集合 regularPostProcessors。（ postProcessBeanFactory() 会在后面执行，先存起来）

			4、 定义一个集合(List 临时变量) currentRegistryProcessors 用于保存当前准备创建的 BeanDefinitionRegistryPostProcessor

			5、去容器中获取 BeanDefinitionRegistryPostProcessor 的 bean 的处理器名称
			internalConfigurationAnnotationProcessor 即 ConfigurationAnnotationProcessor ，
			一般情况都只会获取到一个。此时Spring还未扫描完成，扫描是在 ConfigurationClassPostProcessor 类完成的，
			就是下面的第一个 invokeBeanDefinitionRegistryPostProcessors() 方法

			6、循环 postProcessorNames 即 internalConfigurationAnnotationProcessor 判断是否实现了 PriorityOrdered，
			实现了添加到 currentRegistryProcessors 和 processedBeans 表示它们被处理过了（下一步才处理）

			7、对 currentRegistryProcessors 集合中 BeanDefinitionRegistryPostProcessor 进行排序

			8、将 currentRegistryProcessors 集合加到 registryProcessors 集合中，
			因为 registryProcessors 是装载 BeanDefinitionRegistryPostProcessor，
			一开始的时候，spring只会执行 BeanDefinitionRegistryPostProcessor 独有的方法 postProcessBeanDefinitionRegistry()。
			而不会执行 BeanDefinitionRegistryPostProcessor 父类的方法，即 BeanFactoryProcessor 的方法 postProcessBeanFactory()。
			所以在此统一放到一起等待后续执行

			9、internalConfigurationAnnotationProcessor(currentRegistryProcessors, registry)，
			执行 currentRegistryProcessors 中的 ConfigurationClassPostProcessor 中的 postProcessBeanDefinitionRegistry() 方法，
			这里体现了 Spring 中热插拔，插件化开发的思想，如果不想用这个，不添加就行了。
			从下图可以看到，执行完该方法后 bean 定义 被加载到了 BeanDefinitionMap 中

			10、清空 currentRegistryProcessors ，用完了就需要清空，给后面的其他的重复使用

			11、最后会重复上面的逻辑，调用顺序如下：
			实现了PriorityOrdered接口的
			实现了Ordered接口的
			没有实现任何的优先级接口的
			如果实现了多个的话，将在最先实现的地方调用，第二次将会判断是否已经处理过
		 */
	}

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		// BeanPostProcessorChecker是一个普通的信息打印，可能会有些情况，当Spring的配置中的后处理器还没有被注册就已经开始了bean的初始化时
		// 便会打印出 BeanPostProcessorChecker 中设定的信息
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 使用PriorityOrdered保证顺序
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// MergedBeanDefinitionPostProcessor
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		// 使用Ordered保证顺序
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 无序 BeanPostProcessor
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		// 排序并注册所有实现 PriorityOrdered 的 BeanPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 排序并注册所有实现 Ordered 的 BeanPostProcessor
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		// 注册所有无序的 BeanPostProcessor
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		// 排序并注册所有 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor，
		// 并非重复注册，在beanFactory.addBeanPostProcessor中会先移除已经存在的 BeanPostProcessor
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		// 添加 ApplicationListener 探测器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

	private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
		// Nothing to sort?
		if (postProcessors.size() <= 1) {
			return;
		}
		Comparator<Object> comparatorToUse = null;
		if (beanFactory instanceof DefaultListableBeanFactory) {
			comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
		}
		if (comparatorToUse == null) {
			comparatorToUse = OrderComparator.INSTANCE;
		}
		postProcessors.sort(comparatorToUse);
	}

	/**
	 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
	 */
	private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
					.tag("postProcessor", postProcessor::toString);
			// 调用 BeanDefinitionRegistryPostProcessor 的接口方法
			postProcessor.postProcessBeanDefinitionRegistry(registry);
			postProcessBeanDefRegistry.end();
		}
	}

	/**
	 * Invoke the given BeanFactoryPostProcessor beans.
	 */
	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
					.tag("postProcessor", postProcessor::toString);
			postProcessor.postProcessBeanFactory(beanFactory);
			postProcessBeanFactory.end();
		}
	}

	/**
	 * Register the given BeanPostProcessor beans.
	 */
	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		if (beanFactory instanceof AbstractBeanFactory) {
			// Bulk addition is more efficient against our CopyOnWriteArrayList there
			((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
		}
		else {
			for (BeanPostProcessor postProcessor : postProcessors) {
				beanFactory.addBeanPostProcessor(postProcessor);
			}
		}
	}


	/**
	 * BeanPostProcessor that logs an info message when a bean is created during
	 * BeanPostProcessor instantiation, i.e. when a bean is not eligible for
	 * getting processed by all BeanPostProcessors.
	 */
	private static final class BeanPostProcessorChecker implements BeanPostProcessor {

		private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class);

		private final ConfigurableListableBeanFactory beanFactory;

		private final int beanPostProcessorTargetCount;

		public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) {
			this.beanFactory = beanFactory;
			this.beanPostProcessorTargetCount = beanPostProcessorTargetCount;
		}

		@Override
		public Object postProcessBeforeInitialization(Object bean, String beanName) {
			return bean;
		}

		@Override
		public Object postProcessAfterInitialization(Object bean, String beanName) {
			if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
					this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
				if (logger.isInfoEnabled()) {
					logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
							"] is not eligible for getting processed by all BeanPostProcessors " +
							"(for example: not eligible for auto-proxying)");
				}
			}
			return bean;
		}

		private boolean isInfrastructureBean(@Nullable String beanName) {
			if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {
				BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);
				return (bd.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
			}
			return false;
		}
	}

}
